﻿#region Imports
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MarketPlace.Data.Bases;
using MarketPlace.Data.DomainModels;
using MarketPlace.Web.Models;
using NHibernate;
using NHibernate.Linq;
#endregion

namespace MarketPlace.Web.Controllers
{
    public abstract class BaseCoolListController<T, TKey> : BaseController
        where T : class, new()
    {
        protected abstract bool AllowDelete { get; }

        protected abstract bool AllowInsert { get; }

        protected abstract bool AllowUpdate { get; }

        protected abstract string NHibernateObjectName { get; }

        protected abstract string FriendlyObjectName { get; }

        protected virtual void PrepareEditorData()
        {
        }

        public ActionResult Index()
        {
            return View(GetCoolListViewData);
        }

        protected abstract CoolListViewData GetCoolListViewData { get; }

        protected virtual INHibernateQueryable<T> qry
        {
            get
            {
                return db.Session.Linq<T>();
            }
        }

        protected virtual CoolListRequest ListRequest
        {
            get
            {
                return new CoolListRequest(Request);
            }
        }

        [HttpPost]
        public abstract ActionResult Index(int start);

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Update(string Data)
        {
            var data = GetChangeRecords<T>(Data);

            ClientMessage cs = new ClientMessage();

            cs.Success = data != null;

            if (data != null)
            {
                NHibernate.ITransaction trans = null;

                try
                {
                    trans = db.Session.BeginTransaction();

                    if (data.Created != null && data.Created.Count != 0)
                    {
                        foreach (var domainObject in data.Created)
                        {
                            db.Session.Save(domainObject);
                        }
                    }

                    //if (data.Deleted != null && data.Deleted.Count != 0)
                    //{
                    //    string idToDelete = data.Deleted.Select(x => x.Id.ToString())
                    //        .Aggregate((p, n) => (p + "," + n));

                    //    db.Session.Delete("from " + NHibernateObjectName + " where id in (" + idToDelete + ")");
                    //}

                    if (data.Updated != null && data.Updated.Count != 0)
                    {
                        foreach (var domainObject in data.Updated)
                        {
                            db.Session.Update(domainObject);
                        }
                    }

                    trans.Commit();

                    cs.Success = true;
                }
                catch (Exception ex)
                {
                    if (null != trans)
                        trans.Rollback();

                    cs.Success = false;

                    log.Error(ex);

                    cs.Msg = ex.Message + "<br>posted data failed: <br>" + Data;
                }
            }

            return Json(cs);
        }

        public ActionResult Create()
        {
            PrepareEditorData();

            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(FormCollection fm)
        {
            T data = new T()
            {
            };

            if (TryUpdateModel<T>(data))
            {

                NHibernate.ITransaction trans = null;

                try
                {
                    trans = db.Session.BeginTransaction();

                    db.Session.Save(data);

                    trans.Commit();

                    ViewData["Message"] = "提交" + FriendlyObjectName + "成功";

                    return Redirect(Url.Action("Index"));
                }
                catch (Exception ex)
                {
                    if (null != trans)
                    {
                        trans.Rollback();
                    }

                    ModelState.AddModelError("_Form", ex);

                    log.Error("Create " + NHibernateObjectName + " Failed", ex);
                }
            }

            PrepareEditorData();

            return View();
        }

        public ActionResult Edit(TKey id)
        {
            PrepareEditorData();

            var data = db.Session.Get<T>(id);

            return View(data);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(TKey id, FormCollection fm)
        {
            var data = db.Session.Get<T>(id);

            if (TryUpdateModel<T>(data))
            {
                NHibernate.ITransaction trans = null;

                try
                {
                    trans = db.Session.BeginTransaction();

                    db.Session.Update(data);

                    trans.Commit();

                    ViewData["Message"] = "更新" + FriendlyObjectName + "成功";
                }
                catch (Exception ex)
                {
                    if (null != trans)
                    {
                        trans.Rollback();
                    }

                    ModelState.AddModelError("_Form", ex);

                    log.Error("Edit " + NHibernateObjectName + " Failed", ex);

                    PrepareEditorData();

                    return View(data);
                }
            }
            else
            {
                ModelState.AddModelError("_Form", "TryUpdateModel failed");

                PrepareEditorData();

                return View(data);
            }

            return RedirectToAction("Index");
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Delete(string ids)
        {
            if (ids.IsNullOrEmpty())
            {
                return Auto();
            }

            string sql = string.Format("from " + NHibernateObjectName + " Where id in ({0})", ids);

            NHibernate.ITransaction trans = null;

            try
            {
                trans = db.Session.BeginTransaction();

                int result = db.Session.Delete(sql);

                trans.Commit();

                return Success(string.Format("已删除了{0}个" + FriendlyObjectName, result));
            }
            catch (Exception ex)
            {
                if (null != trans)
                {
                    trans.Rollback();
                }

                log.Error("Delete " + NHibernateObjectName + " Failed", ex);

                return Auto("删除" + FriendlyObjectName + "失败:" + ex.Message);
            }
        }
    }
}
